package x.ovo.wechat.bot.plugin;

import lombok.NonNull;
import lombok.extern.slf4j.Slf4j;
import x.ovo.wechat.bot.core.Context;
import x.ovo.wechat.bot.core.contact.RetrievalType;
import x.ovo.wechat.bot.core.entity.Contact;
import x.ovo.wechat.bot.core.entity.Member;
import x.ovo.wechat.bot.core.entity.Recommend;
import x.ovo.wechat.bot.core.enums.ContactType;
import x.ovo.wechat.bot.core.event.EventListener;
import x.ovo.wechat.bot.core.event.MessageEvent;
import x.ovo.wechat.bot.core.message.Message;
import x.ovo.wechat.bot.core.message.TextMessage;
import x.ovo.wechat.bot.core.message.VerifyMessage;
import x.ovo.wechat.bot.core.plugin.Plugin;

import java.util.Objects;

@Slf4j(topic = "GroupInvite")
@SuppressWarnings({"DuplicatedCode", "LoggingSimilarMessage"})
public class GroupInviteListener extends EventListener<MessageEvent<Message>, Message> {

    private final Context ctx;

    public GroupInviteListener(Plugin plugin) {
        super(plugin);
        this.ctx = plugin.getContext();
    }

    @Override
    public boolean support(@NonNull MessageEvent<Message> event, Message source) {
        // 消息类型时好友请求验证消息或私聊消息正文包含关键词
        return source instanceof VerifyMessage || (!source.isGroup() && this.plugin.<String>getConfig().containsKey(source.getContent()));
    }

    @Override
    public boolean onEvent(@NonNull MessageEvent<Message> event, Message source) {
        if (source instanceof TextMessage message) this.handleTextMessage(message);
        if (source instanceof VerifyMessage message) this.handleVerifyMessage(message.getRecommend());
        return true;
    }

    /**
     * 处理私聊的文本消息
     *
     * @param message 文本消息
     */
    private void handleTextMessage(Message message) {
        String groupNickname = this.plugin.<String>getConfig().get(message.getContent());
        Contact contact = this.ctx.getContactManager().get(groupNickname, RetrievalType.NICK_NAME);

        if (Objects.isNull(contact)) {
            log.error("{} 不存在，请检查配置文件", groupNickname);
            return;
        }
        if (!ContactType.GROUP.equals(contact.getType())) {
            log.error("{} 不是群聊，无法邀请成员加入", groupNickname);
            return;
        }
        Member member = this.ctx.getContactManager().get(contact.getUserName(), message.getFrom().getUserName(), RetrievalType.USER_NAME);
        if (Objects.nonNull(member)) {
            log.info("{} 已经在群聊 [{}] 中了", message.getFrom().getNickName(), contact.getNickName());
            message.getFrom().sendMessage("你已经在群聊 [" + contact.getNickName() + "] 中了");
            return;
        }

        boolean b = this.ctx.getApi().inviteMember(contact.getUserName(), message.getFrom().getUserName());
        log.info("邀请 {} 加入群聊 [{}] {}", message.getFrom().getNickName(), contact.getNickName(), b ? "成功" : "失败");
    }


    private void handleVerifyMessage(Recommend recommend) {
        boolean b = this.ctx.getApi().verifyUser(recommend);
        log.info("验证好友 {} {}", recommend.getNickName(), b ? "成功" : "失败");

        if (!this.plugin.<String>getConfig().containsKey(recommend.getContent())) return;

        String groupNickname = this.plugin.<String>getConfig().get(recommend.getContent());
        Contact contact = this.ctx.getContactManager().get(groupNickname, RetrievalType.NICK_NAME);

        if (Objects.isNull(contact)) {
            log.error("{} 不存在，请检查配置文件", groupNickname);
            return;
        }
        if (!ContactType.GROUP.equals(contact.getType())) {
            log.error("{} 不是群聊，无法邀请成员加入", groupNickname);
            return;
        }
        Member member = this.ctx.getContactManager().get(contact.getUserName(), recommend.getUserName(), RetrievalType.USER_NAME);
        if (Objects.nonNull(member)) {
            log.info("{} 已经在群聊 [{}] 中了", recommend.getNickName(), contact.getNickName());
            this.ctx.getApi().sendText(recommend.getUserName(), "你已经在群聊 [" + contact.getNickName() + "] 中了");
            return;
        }

        b = this.ctx.getApi().inviteMember(contact.getUserName(), recommend.getUserName());
        log.info("邀请 {} 加入群聊 [{}] {}", recommend.getNickName(), contact.getNickName(), b ? "成功" : "失败");
    }

    @Override
    public boolean executeNext() {
        return false;
    }
}
